//Read and send all digital and analog inputs out over serial (e.g. to vvvv).
// small characters toggle off, capital ones toggle on
// a/A enables the arduino
// b/B switches the ambient light
// c/C switches the pulse light
//
//Sends a string with the format "bool \t bool \t bool \t int \t int \t bool \t bool \t \t\r\n"
//where:
// first parameter identicates if arduino is enabled
// second parameter verifies that ambient light is switched on
// third parameter verifies that pulse light is switched on
// fourth parameter identicates the id  of the active pipette
//    note that an id of 8 indicates no active pipette
// fifth parameter identicates the current state of the micro poti
// sixth parameter indicates that user wants to reset the installation
// seventh parameter indicates that user wants to reboot all computers
//example: 1  1  0  -1  345 0 0 

boolean started = false;
boolean ambientLight = false;
boolean pulseLight = false;


// DIGITAL
int resetPin[2] = {2, 3}; // digital
int pipetteLightPin[4] = {7,6,5,4}; // digital
int microLightPin[4] = {8,9,10,11}; // digital
int ambientLightPin = 12; // digital
int ledPin = 13; // digital

// ANALOG
int potPin = 0; // analog
int pipettePin[4] = {2,3,4,5}; // analog

// STATE VALUES
boolean reset = false;
boolean restart = false;

int activePipette = 8; // 0..3 for active, 8 for inactive
int micro = 0; // 0..1024

// FLAGS
boolean pipette[4]= {false, false, false, false};;
unsigned long counter=0;

boolean resetPressed[2]  = {false, false};
unsigned long resetCounter[2]  = {0, 0};  

boolean restartPressed = false;
unsigned long restartCounter = 0;

unsigned long lastMillis = 0;


void setup() {
  Serial.begin(9600); // Digital Pin 0 and 1 are now reserved for RX/TX signal indicators

//  Initialize all digital Pins
  pinMode(ambientLightPin, OUTPUT);
  pinMode(ledPin, OUTPUT);

  int i=0;
  for (i=0;i<2;i++) pinMode(resetPin[i], INPUT);
  for (i=0;i<4;i++) pinMode(pipetteLightPin[i], OUTPUT);
  for (i=0;i<4;i++) pinMode(microLightPin[i], OUTPUT);
}


boolean checkPipette(boolean debug) {
// is one of the pipette switches pressed?
  int val;
  for (int i=0;i<4;i++) {
    val = analogRead(pipettePin[i]);  // read input value
    if (val <= 512) {            // check if the input is HIGH
      if (activePipette != 8) digitalWrite(pipetteLightPin[activePipette], LOW);
      activePipette = i;
      digitalWrite(pipetteLightPin[activePipette], HIGH);
      counter = millis();
      
      if (millis()%200 < 100) debug = true; 
    } 
  }

// activate the corresponding Light  
  if (activePipette != 8) {
    if ( counter + 8000 <= millis() ) {
      digitalWrite(pipetteLightPin[activePipette], LOW);
      activePipette = 8;
    }
  } 

  return debug;
}

boolean checkMicro(boolean debug) {
  int currentMicro =  analogRead(potPin); 
  
  long delta = ((currentMicro-micro)*0.23);
  if (abs(delta) > 1.5)  micro += int(delta);
//  micro = currentMicro;
  
//  int tissue = int(micro / 256);
  
  // alle lichter aus, richtiges an
  for (int i = 0;i<4;i++) digitalWrite(microLightPin[i], LOW);
  boolean on = HIGH;
  if ((micro >=0) && (micro < 77)) digitalWrite(microLightPin[3], on);
  if ((micro >=260) && (micro < 367)) digitalWrite(microLightPin[2], on);
  if ((micro >=517) && (micro < 627)) digitalWrite(microLightPin[1], on);
  if ((micro >=895) && (951)) digitalWrite(microLightPin[0], on);


  return debug;
}

boolean checkReset(boolean debug) {
  boolean r[2] = {false, false};
  
  boolean doReset = false;
  int i = 0;
  for (i = 0;i<2;i++) {
    r[i] = digitalRead(resetPin[i]);
    
    if (!r[i]) {
      if (!resetPressed[i]) {
        resetPressed[i] = true;
        resetCounter[i] = millis() + 1000;
      } 
    } else resetPressed[i] = false; 
    if (resetPressed[i] && (resetCounter[i] < millis())) doReset = true;
  }
  

  if (resetPressed[0] && resetPressed[1]) {
     if (!restartPressed) {
        restartPressed = true; 
        restartCounter = millis() + 4000;
      } 
      
      reset = false;
      resetPressed[0] = resetPressed[1] = false;
      
      if (restartPressed && (restartCounter < millis())) {
        restart = true;  
      
      if (((8000/(restartCounter-millis()))%2) < 1) debug = true;
      
    }
  } else {
    reset = doReset;
    restartPressed  = false;
    restart = false;
  } 

  return debug;
}

void updateLight() {
  if (ambientLight && pulseLight) {
     if (millis()%500 < 250) digitalWrite(ambientLightPin, HIGH);
       else digitalWrite(ambientLightPin, LOW);
    
   } else {
     if (ambientLight) 
       digitalWrite(ambientLightPin, HIGH);
       else digitalWrite(ambientLightPin, LOW);
     }
}

void updateDebug(boolean debug) {
  digitalWrite( ledPin, debug);
 
} 

void deactivate() {

  for (int i=0;i<13;i++) {
    digitalWrite(i, LOW);
  }  
  
}

void validateMillis() {
  unsigned long now = millis();
  
  if (now < lastMillis) {
    int i = 0;
    for (i=0;i<4;i++) pipette[i] = false;
    activePipette = 8;
    
    for (i=0;i<2;i++) resetPressed[i] = false;
    restartPressed = false;    
    
    restartCounter = resetCounter[0] = resetCounter[1] = counter = 0;
  }
  lastMillis = now;  
}

void loop(){
//  debug(activePipette);
  validateMillis();

  int serialGet = Serial.read();
  if (serialGet != -1) { // data is valid
     if (serialGet=='C') pulseLight = true;
     if (serialGet=='c') pulseLight = false;

     if (serialGet=='B') ambientLight = true;
     if (serialGet=='b') ambientLight = false;

     if (serialGet=='A') started = true;
     if (serialGet=='a') started = false;

  }

  boolean debug = false;
  if (started) {
     debug = checkPipette(debug);
     debug = checkMicro(debug);
     debug = checkReset(debug);
     updateLight();
     updateDebug(debug);
   } else deactivate();
  
  Serial.print(started, DEC);
  Serial.print("\t");

  Serial.print(ambientLight, DEC);
  Serial.print("\t");

  Serial.print(pulseLight, DEC);
  Serial.print("\t");

  Serial.print(activePipette);
  Serial.print("\t");

  Serial.print(micro);
  Serial.print("\t");

  Serial.print(reset, DEC);
  Serial.print("\t");

  Serial.print(restart, DEC);
  Serial.print("\t");


  //print carriage return and newline
   Serial.println();
 

}

